基本概念
ECMAScript 中的一切(变量、函数名和操作符)都区分大小写,函数名不能使用 typeof,因为它 是一个关键字,但 typeOf 则完全可以是一个有效的函数名。
- 标识符
标识符,就是指变量、函数、属性的名字,或者函数的参数。标识符的格式:
- 第一个字符必须是一个字母、下划线(_)或一个美元符号($);
- 其他字符可以是字母、下划线、美元符号或数字。
- 按照惯例,ECMAScript 标识符采用驼峰大小写格式,也就是第一个字母小写,剩下的每个单词的
首字母大写。
==不能把关键字、保留字、true、false 和 null 用作标识符==
- 注释
ECMAScript的注释包括单行注释和块级注释。
单行注释以两个斜杠开头:
|
|
块级注释以一个斜杠和一个星号开头,以一个星号和一个斜杠结尾:
|
|
- 严格模式
ECMAScript 5 引入了严格模式(strict mode)的概念。严格模式是为 JavaScript 定义了一种不同的 解析与执行模型。在严格模式下,ECMAScript 3 中的一些不确定的行为将得到处理,而且对某些不安全 的操作也会抛出错误。要在整个脚本中启用严格模式,可以在顶部添加如下代码:
|
|
在函数内部的上方包含这条编译指示,也可以指定函数在严格模式下执行:
|
|
- 语句
ECMAScript 中的语句以一个分号结尾;如果省略分号,则由解析器确定语句的结尾。
|
|
1.2 关键字和保留字(了解)
ECMA描述了一组具有特定用途的关键字,这些关键字可用于表示控制语句的开始或结束,或 者用于执行特定操作等。按照规则,关键字也是语言保留的,不能用作标识符。ECMAScript的关键字:
break | do | instanceof | typeof |
---|---|---|---|
case | else | new | var |
catch | finally | return | void |
continue | for | switch | while |
debugger | function | this | with |
default | if | throw | delete |
in | try | abstract | enum |
int | short | boolean | export |
interface | static | byte | extends |
long | super | char | final |
native | synchronized | class | float |
package | throws | const | goto |
private | transient | debugger | implements |
protected | volatile | double | import |
public |
第 5 版把在非严格模式下运行时的保留字缩减为下列这些:
class | enum | extends | super |
---|---|---|---|
const | export | import |
在严格模式下,第 5 版还对以下保留字施加了限制:
implements | package | public |
---|---|---|
interface | private | static |
let | protected | yield |
1.3 变量
ECMAScript 的变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据。定义变量时要使用 var 操作符,后跟变量名。
- 全局变量
- 局部变量
1.4 数据类型
ECMAScript 中有 6 种简单数据类型(也称为基本数据类型):Undefined、Null、Boolean、Number 、String和Symbol(es6新增一种Symbol)。还有 1 种复杂数据类型——Object。1.4.1 typeof操作符
检测数据类型的一种方法。
“undefined”——如果这个值未定义;
“boolean”——如果这个值是布尔值;
“string”——如果这个值是字符串;
“number”——如果这个值是数值;
“object”——如果这个值是对象或 null;
“function”——如果这个值是函数;
“symbol”–如果这个值是Symbol。
有些时候,typeof 操作符会返回一些令人迷惑但技术上却正确的值。比如,调用 typeof null 会返回”object”,因为特殊值 null 被认为是一个空的对象引用。
1.4.2 Undefined类型
Undefined 类型只有一个值,即特殊的 undefined。在使用 var 声明变量但未对其加以初始化时,这个变量的值就是 undefined,对于尚未声明过的变量,只能执行一项操作,即使用 typeof 操作符检测其数据类型。
1.4.3 Null类型
Null 类型是第二个只有一个值的数据类型,这个特殊的值是 null。从逻辑角度来看,null 值表 示一个空对象指针,而这也正是使用 typeof 操作符检测 null 值时会返回”object”的原因,如下面 的例子所示:
|
|
如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为 null 而不是其他值。这样 一来,只要直接检查 null 值就可以知道相应的变量是否已经保存了一个对象的引用,如下面的例子 所示:
|
|
实际上,undefined 值是派生自 null 值的,因此 ECMA-262 规定对它们的相等性测试要返回 true:
|
|
如前所述,无论在什么情况下 都没有必要把一个变量的值显式地设置为 undefined,可是同样的规则对 null 却不适用。换句话说, 只要意在保存对象的变量还没有真正保存对象,就应该明确地让该变量保存 null 值。这样做不仅可以 体现 null 作为空对象指针的惯例,而且也有助于进一步区分 null 和 undefined。
1.4.4 Boolean类型
Boolean类型只有两个字面值:true 和 false。
要将一个值转换为其对应的 Boolean 值,可以调用转型函数 Boolean()。
各种数据类型及其对 应的转换规则:
数据类型 | 转换为true的值 | 转换为false的值 |
---|---|---|
Boolean | true | false |
String | 任何非空字符串 | “”(空字符串) |
Number | 任何非零数字值(包括无穷大) | 0和NaN |
Object | 任何对象 | null |
Undefined | undefined |
1.4.5 Number类型
- 浮点数值
==0.1 + 0.2 != 0.3==
关于浮点数值计算会产生舍入误差的问题,有一点需要明确:这是使用基于 IEEE754 数值的浮点计算的通病,ECMAScript 并非独此一家;其他使用相同数值格式的语言也存在这个问题。
- 数值范围
由于内存的限制,ECMAScript 并不能保存世界上所有的数值。
ECMAScript 能够表示的最小数值是 5e-324;最大数值是1.7976931348623157e+308
Infinity/-Infinity
要想确定一个数值是不是有穷的
,可以使用 isFinite()函数。
- NaN
NaN,即非数值(Not a Number)是一个特殊的数值,这个数值用于表示一个本来要返回数值的操作数
未返回数值的情况(这样就不会抛出错误了)。
在 ECMAScript 中,任何数值除以 0 会返回 NaN1,因此不会影响其他代码的执行。NaN 与任何值都不相等,包括 NaN 本身。
要想确定一个参数是不是NaN,
ECMAScript 定义了 isNaN()函数。
isNaN()也适用于对象。在基于对象调用 isNaN() 函数时,会首先调用对象的 valueOf()方法,然后确定该方法返回的值是否可以转 换为数值。如果不能,则基于这个返回值再调用 toString()方法,再测试返回值。 而这个过程也是 ECMAScript 中内置函数和操作符的一般执行流程。
- 数值转换
有3个函数可以把非数值转换为数值:Number()、parseInt()和 parseFloat()。
第一个函数, 即转型函数 Number()可以用于任何数据类型,而另两个函数则专门用于把字符串转换成数值。
Number()函数的转换规则:
(1). 如果是 Boolean 值,true 和 false 将分别被转换为 1 和 0。
(2). 如果是数字值,只是简单的传入和返回。
(3). 如果是 null 值,返回 0。
(4). 如果是 undefined,返回 NaN。
(5). 如果是字符串,遵循下列规则:
- 如果字符串中只包含数字(包括前面带正号或负号的情况),则将其转换为十进制数值,即”1” 会变成 1,”123”会变成 123,而”011”会变成 11(注意:前导的零被忽略了);
- 如果字符串中包含有效的浮点格式,如”1.1”,则将其转换为对应的浮点数值(同样,也会忽 略前导零);
- 如果字符串中包含有效的十六进制格式,例如”0xf”,则将其转换为相同大小的十进制整 数值;
- 如果字符串是空的(不包含任何字符),则将其转换为 0;
- 如果字符串中包含除上述格式之外的字符,则将其转换为 NaN。
(6). 如果是对象,则调用对象的 valueOf()方法,然后依照前面的规则转换返回的值。如果转换
的结果是 NaN,则调用对象的 toString()方法,然后再次依照前面的规则转换返回的字符串值。
parseInt()函数的转换规则:
parseInt()函数在转换字符串时,更多的是看其是否符合数值模式。它会忽略字 符串前面的空格,直至找到第一个非空格字符。如果第一个字符不是数字字符或者负号,parseInt() 就会返回 NaN;也就是说,用 parseInt()转换空字符串会返回 NaN(Number()对空字符返回 0)。如 果第一个字符是数字字符,parseInt()会继续解析第二个字符,直到解析完所有后续字符或者遇到了 一个非数字字符。
parseInt()函数提供第二个参数:转换时使用的基数(即多少进制)。
|
|
parseFloat()函数的转换规则:
parseFloat()也是从第一个字符(位置 0)开始解析每个字符。而且 也是一直解析到字符串末尾,或者解析到遇见一个无效的浮点数字字符为止。也就是说,字符串中的第 一个小数点是有效的,而第二个小数点就是无效的了,因此它后面的字符串将被忽略。
parseFloat()与 parseInt()的第二个区别在于它始终都会忽略前导 的零。parseFloat()可以识别前面讨论过的所有浮点数值格式,也包括十进制整数格式。但十六进制格 式的字符串则始终会被转换成 0。由于 parseFloat()只解析十进制值,因此它没有用第二个参数指定基 数的用法。
1.4.6 String类型
字符串可以由双
引号(“)或单引号(‘)表示。
(1). 字符字面量(转移字符)
字面量 | 含义 |
---|---|
\n | 换行 |
\t | 制表 |
\b | 空格 |
\r | 回车 |
\f | 换页 |
\ | 斜杠 |
\’ | 单引号(‘),在用单引号表示的字符串中使用。例如:’He said, \’hey.\’’ |
\” | 双引号(“),在用双引号表示的字符串中使用。例如:”He said, \”hey.\”” |
\xnn | 以十六进制代码nn表示的一个字符(其中n为0~F)。例如,\x41表示”A” |
\unnnn | 以十六进制代码nnnn表示的一个Unicode字符(其中n为0~F)。例如,\u03a3表示希腊字符Σ |
(2). 转化为字符串
|
|
toString();
要把一个值转换为一个字符串有两种方式。第一种是使用几乎每个值都有的 toString()方法,这个方法唯一要做的就是返回相应值的字符串表现。
==数值、布尔值、对象和字符串值都有 toString()方法。但 null 和 undefined 值没有这个方法。==
多数情况下,调用 toString()方法不必传递参数。但是,在调用数值的 toString()方法时,可 以传递一个参数:输出数值的基数。toString()可以输出以二进制、八进制、十六进制,乃至其他任意有效进制格 式表示的字符串值。
|
|
String();
在不知道要转换的值是不是 null 或 undefined 的情况下,还可以使用转型函数 String(),这个函数能够将任何类型的值转换为字符串。String()函数转换规则:
- 如果值有 toString()方法,则调用该方法(没有参数)并返回相应的结果;
- 如果值是 null,则返回”null”;
- 如果值是 undefined,则返回”undefined”。
1.4.7 Object类型
ECMAScript中的对象其实就是一组数据和功能的集合。
如果不给构造函数传递参数,则可以省略后面的那一对圆括号(不推荐)。
Object 的每个实例都具有下列属性和方法:
- constructor:保存着用于创建当前对象的函数。对于前面的例子而言,构造函数(constructor) 8 就是 Object()。
- hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例 的原型中)是否存在。其中,作为参数的属性名(propertyName)必须以字符串形式指定(例 如:o.hasOwnProperty(“name”))。
- isPrototypeOf(object):用于检查传入的对象是否是传入对象的原型。
- propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用 for-in 语句来枚举。与hasOwnProperty()方法一样,作为参数的属性名必须以字符串形式指定。
- toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应。
- toString():返回对象的字符串表示。
- valueOf():返回对象的字符串、数值或布尔值表示。通常与toString()方法的返回值相同。
由于在 ECMAScript 中 Object 是所有对象的基础,因此所有对象都具有这些基本的属性和方法。
1.5 操作符
ECMA 描述了一组用于操作数据值的操作符,包括算术操作符(如加号和减号)、位操作符、关系操作符和相等操作符。==在应用于对象时,相应的操作符通常都会调用对象的valueOf()和(或)toString()方法,以便取得可以操作的值==。
1.5.1 一元操作符
只能操作一个值的操作符叫做一元操作符。
(1). 递增和递减操作符
前置递减/后置递减 or 前置递增/后置递增
|
|
|
|
(2). 一元加和减操作符(略)
1.5.2 位操作符(略)
1.5.3 布尔操作符
==布尔操作符一共有 3 个:非!(NOT)、与&&(AND) 和或||(OR)。==
1. 逻辑非
逻辑非操作符由一个叹号(!)表示。逻辑非操作符首先会将它的操作数转换为一个布尔值,然后再对其求反,逻辑非操作符遵循下列规则:
- 如果操作数是一个对象,返回 false;
- 如果操作数是一个空字符串,返回 true;
- 如果操作数是一个非空字符串,返回 false;
- 如果操作数是数值 0,返回 true;
- 如果操作数是任意非 0 数值(包括 Infinity),返回 false;
- 如果操作数是 null,返回 true;
- 如果操作数是 NaN,返回 true;
- 如果操作数是 undefined,返回 true。
2. 逻辑与
逻辑与操作符由两个和号(&&)表示,有两个操作数。
两个操作数都是布尔值(略)。
有一个操作数不是布尔值遵循下列规则:
- 如果第一个操作数是对象,则返回第二个操作数;
- 如果第二个操作数是对象,则只有在第一个操作数的求值结果为 true 的情况下才会返回该对象;
- 如果两个操作数都是对象,则返回第二个操作数;
- 如果有一个操作数是 null,则返回 null;
- 如果有一个操作数是 NaN,则返回 NaN;
- 如果有一个操作数是 undefined,则返回 undefined。
逻辑与操作属于短路操作,即如果第一个操作数能够决定结果,那么就不会再对第二个操作数求值。
3. 逻辑或
逻辑或操作符由两个竖线符号(||)表示,有两个操作数,
两个操作数都是布尔值(略)。
有一个操作数不是布尔值遵循下列规则:
- 如果第一个操作数是对象,则返回第一个操作数;
- 如果第一个操作数的求值结果为 false,则返回第二个操作数;
- 如果两个操作数都是对象,则返回第一个操作数;
- 如果两个操作数都是 null,则返回 null;
- 如果两个操作数都是 NaN,则返回 NaN;
- 如果两个操作数都是 undefined,则返回 undefined。
与逻辑与操作符相似,逻辑或操作符也是短路操作符。
1.5.4 乘性操作符
3个乘性操作符:乘法、除法和求模
乘法、除法(省略)
求模:求模操作符会遵循下列特殊规则来处理特殊的值:
- 如果操作数都是数值,执行常规的除法计算,返回除得的余数;
- 如果被除数是无穷大值而除数是有限大的数值,则结果是 NaN;
- 如果被除数是有限大的数值而除数是零,则结果是 NaN;
- 如果是 Infinity 被 Infinity 除,则结果是 NaN;
- 如果被除数是有限大的数值而除数是无穷大的数值,则结果是被除数;
- 如果被除数是零,则结果是零;
- 如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值,然后再应用上面的规则。
1.5.5 加性操作符
1. 加法
如果==两个操作符都是数值==,执行常规的加法计算,然后根据下列规则返回结果:
- 如果有一个操作数是 NaN,则结果是 NaN;
- 如果是 Infinity 加 Infinity,则结果是 Infinity;
- 如果是-Infinity 加-Infinity,则结果是-Infinity;
- 如果是 Infinity 加-Infinity,则结果是 NaN;
如果==有一个操作数是字符串==,那么就要应用如下规则:
- 如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来;
- 如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接
起来。
如果==有一个操作数是对象、数值或布尔值==,则调用它们的 toString()方法取得相应的字符串值,
然后再应用前面关于字符串的规则。对于 undefined 和 null,则分别调用 String()函数并取得字符 串”undefined”和”null”。
2. 减法
减法操作符运算规则:
- 如果两个操作符都是数值,则执行常规的算术减法操作并返回结果;
- 如果有一个操作数是 NaN,则结果是 NaN;
- 如果是 Infinity 减 Infinity,则结果是 NaN;
- 如果是-Infinity 减-Infinity,则结果是 NaN;
- 如果是 Infinity 减-Infinity,则结果是 Infinity;
- 如果是-Infinity 减 Infinity,则结果是-Infinity;
- 如果有一个操作数是字符串、布尔值、null 或 undefined,则先在后台调用 Number()函数将
其转换为数值,然后再根据前面的规则执行减法计算。如果转换的结果是 NaN,则减法的结果
就是 NaN; - 如果有一个操作数是对象,则调用对象的 valueOf()方法以取得表示该对象的数值。如果得到
的值是 NaN,则减法的结果就是 NaN。如果对象没有 valueOf()方法,则调用其 toString()
方法并将得到的字符串转换为数值。1.5.6 关系操作符
小于(<)、大于(>)、小于等于(<=)和大于等于(>=),运算规则: - 如果两个操作数都是数值,则执行数值比较。
- 如果两个操作数都是字符串,则比较两个字符串对应的字符编码值。
- 如果一个操作数是数值,则将另一个操作数转换为一个数值,然后执行数值比较。
- 如果一个操作数是对象,则调用这个对象的 valueOf()方法,用得到的结果按照前面的规则执
行比较。如果对象没有 valueOf()方法,则调用 toString()方法,并用得到的结果根据前面
的规则执行比较。 - 如果一个操作数是布尔值,则先将其转换为数值,然后再执行比较。
==常见的奇怪的现象:==
==根据规则,任何操作数与 NaN 进行关系比较,结果都是 false。==
1.5.7 相等操作符
1. 相等和不相等
运算规则:
- 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false 转换为 0,而
true 转换为 1; - 如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值;
- 如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf()方法,用得到的基本类
型值按照前面的规则进行比较; - null 和 undefined 是相等的。
- 要比较相等性之前,不能将 null 和 undefined 转换成其他任何值。
- 如果有一个操作数是 NaN,则相等操作符返回 false,而不相等操作符返回 true。重要提示:
即使两个操作数都是 NaN,相等操作符也返回 false;因为按照规则,NaN 不等于 NaN。 - 如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,
则相等操作符返回 true;否则,返回 false。2. 全等和不全等(略)
1.5.8 逗号操作符
使用逗号操作符可以在一条语句中执行多个操作,如下面的例子所示:1var num1=1, num2=2, num3=3;
逗号操作符多用于声明多个变量;但除此之外,逗号操作符还可以用于赋值。在用于赋值时,逗号 操作符总会返回表达式中的最后一项,如下面的例子所示:
1.6 语句
1.6.1 if语句(略)
1.6.2 do-while语句(略)
do-while 语句是一种后测试循环语句,循环体内的代码至少会被执行一次
1.6.3 while语句(略)
1.6.4 for语句(略)
1.6.5 for-in语句
for-in 语句是一种精准的迭代语句,可以用来枚举对象的属性。以下是 for-in 语句的语法:
示例:
1.6.6 break和continue语句
==break 和 continue 语句用于在循环中精确地控制代码的执行。其中,break 语句会立即退出循环, 强制继续执行循环后面的语句。而 continue 语句虽然也是立即退出循环,但退出循环后会从循环的顶部继续执行。==
1.6.7 switch语句
switch语法:
如果合并多个case,添加注释
1.7 函数
函数的基本语法:
严格模式对函数有一些限制:
- 不能把函数命名为 eval 或 arguments;
- 不能把参数命名为 eval 或 arguments;
- 不能出现两个命名参数同名的情况。
1.7.1 理解函数参数
ECMAScript 中的参数在内部是用一个类数组来表示的,
可以使用方括号语法访问它的每一个元素,例如arguments[0],也可以用length属性来确定传递进来多少个参数1.7.2 没有重载
ECMAScript 函数不能像传统意义上那样实现重载。而在其他语言(如 Java)中,可以为一个函数 编写两个定义,只要这两个定义的签名(接受的参数的类型和数量)不同即可。如前所述,ECMAScirpt 函数没有签名,因为其参数是由包含零或多个值的数组来表示的。而没有函数签名,真正的重载是不可 能做到的。
通过检查传入函数中参数的类型和数量并作出不同的反应,可以模仿方法的重载。
1.8 小结
ECMAScript 中包含了所有基本的语法、操作符、数据类型以及完成基本的计算任务所必需的对象,但没有对取得输入和产生输出的机制作出规定。
以下简要总结了 ECMAScript 中基本的要素:
- ECMAScript中的基本数据类型包括 Undefined、Null、Boolean、Number、String和Symbol(ES6新增)
- 与其他语言不同,ECMScript 没有为整数和浮点数值分别定义不同的数据类型,Number 类型可
用于表示所有数值。 - ECMAScript中也有一种复杂的数据类型,即 Object类型,该类型是这门语言中所有对象的基
础类型。 - 严格模式为这门语言中容易出错的地方施加了限制。
- ECMAScript 提供了很多与C及其他类 C语言中相同的基本操作符,包括算术操作符、布尔操作符、关系操作符、相等操作符及赋值操作符等。
- ECMAScript从其他语言中借鉴了很多流控制语句,例如if语句、for语句和switch语句等。ECMAScript中的函数与其他语言中的函数有诸多不同之处。
- 无须指定函数的返回值,因为任何 ECMAScript函数都可以在任何时候返回任何值。
- 实际上,未指定返回值的函数返回的是一个特殊的 undefined值。
- ECMAScript中也没有函数签名的概念,因为其函数参数是以一个包含零或多个值的数组的形式传递的
- 可以向 ECMAScript 函数传递任意数量的参数,并且可以通过 arguments 对象来访问这些参数
- 由于不存在函数签名的特性,ECMAScript 函数不能重载。